package com.zn.controller;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.zn.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;

/**
 * 通用
 *
 * @author 码农小周
 * @since 2023-05-12
 */
@Slf4j
@RestController
@RequestMapping("/common")
@Api(tags = "通用操作相关")
public class CommonController {

    @Value("${businessCard.path}")
    private String basePath;

    /**
     * 获取验证码
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     * @return Result<String>
     */
    @GetMapping("/getCaptcha")
    @ApiOperation(value = "获取验证码", notes = "生成一个验证码图片，并将图片中的验证码存在域中")
    public Result<String> getCaptcha(HttpServletRequest request, HttpServletResponse response) {

        try (
                //获取response输出流对象
                ServletOutputStream outputStream = response.getOutputStream();
        ) {
            //定义图形验证码的长、宽、验证码字符数、干扰线宽度
            ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(120, 40, 4, 2);
            //写入浏览器
            shearCaptcha.write(outputStream);
            //将生成的验证码code放入Session中
            request.getSession().setAttribute("code", shearCaptcha.getCode());

        } catch (IOException e) {
            throw new RuntimeException();
        }
        return Result.success("图片验证码获取成功");
    }

    /**
     * 文件上传
     *
     * @param multipartFile 文件对象
     * @return Result<String>
     */

    @PostMapping("/upload")
    @ApiOperation(value = "文件上传")
    @CrossOrigin
    public Result<String> upload(@RequestPart("file") MultipartFile multipartFile) {
        //获取原文件名
        String originalFilename = multipartFile.getOriginalFilename();

        //判断文件名是否存在
        if (originalFilename == null) {
            return Result.error(500,"文件不存在");
        }

        //获取文件后缀名
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        //生成新的文件名
        String fileName = UUID.randomUUID() + suffix;

        //判断文件夹是否存在
        File fileDir = new File(basePath);
        if (!fileDir.exists()) {
            boolean mkdirs = fileDir.mkdirs();
            log.info(mkdirs ? "文件夹创建成功" : "文件夹创建失败");
        }

        try {
            //把文件上传到指定位置
            multipartFile.transferTo(new File(fileDir +"\\"+ fileName));
        } catch (IOException e) {
            throw new RuntimeException();
        }

        return Result.success(fileName);
    }

    /**
     * 文件下载
     *
     * @param fileName 文件名
     */
    @GetMapping("/download")
    @ApiOperation(value = "文件下载")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "fileName",value = "文件名",dataType = "String",paramType = "query",required = true)
    })
    @CrossOrigin
    public void download(String fileName, HttpServletResponse response) {
        try (
                //获取缓冲文件字节输入流（从磁盘到内存）
                final BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(basePath +"\\"+ fileName));
                //获取缓冲响应字节输出流（内存输出到网页）
                final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
        ) {
            //设置响应回去的文件类型
            response.setContentType("image/png");

            int len;
            final byte[] bytes = new byte[1024];
            //往bytes数组中读数据（等于-1代表没有数据了）
            while ((len = bufferedInputStream.read(bytes)) != -1) {
                //往网页响应bytes数组中的数据
                bufferedOutputStream.write(bytes, 0, len);
            }

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}
